package cn.itsource.org.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import cn.itsource.common.exception.BusinessException;
import cn.itsource.common.util.AjaxResult;
import cn.itsource.common.util.SMSUtils;
import cn.itsource.common.util.StrUtils;
import cn.itsource.common.util.VerifyCodeUtils;
import cn.itsource.org.domain.Logininfo;
import cn.itsource.org.domain.User;
import cn.itsource.org.mapper.LogininfoMapper;
import cn.itsource.org.mapper.UserMapper;
import cn.itsource.org.myenum.Constant;
import cn.itsource.org.ro.RegisterImgRo;
import cn.itsource.org.ro.RegisterUserPhoneRo;
import cn.itsource.org.service.IRegisterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
public class RegisterServiceImpl implements IRegisterService {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private SMSUtils smsUtils;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private LogininfoMapper logininfoMapper;

    @Override
    public AjaxResult verifyCode(String key) {
        //得到key
        //获取随机码
        String randomString = StrUtils.getRandomString(4);
        //生成图片验证码
        String imgCode = VerifyCodeUtils.verifyCode(115, 45, randomString);
        //保存redis 并设置好过期时间
        redisTemplate.opsForValue().set(key,randomString,5, TimeUnit.MINUTES);
        return AjaxResult.me().setResultObj(imgCode);
    }

    @Override
    public AjaxResult checkImage(RegisterImgRo registerImgRo) {
        //分析  你要做什么事情
        //1.从reids里面去取  看  有没有
        Object o = redisTemplate.opsForValue().get(registerImgRo.getImageCodeKey());
        if(o == null){
            throw new BusinessException("图片验证码以过期");
        }
        //判断 redis里面的值 和你用户填的值是否一致

        if(!o.toString().equals(registerImgRo.getImageCode())){
            throw new BusinessException("图片验证码输入不正确");
        }
        //给对于的手机号发送短信验证码
        String newCode = StrUtils.getRandomString(6);
//        smsUtils.sendMsg(registerImgRo.getPhone(),code);

        //先去取
        Object oldCode = redisTemplate.opsForValue().get(registerImgRo.getPhone() +
                Constant.REGISTER_PHONE);
        if(oldCode == null){
            redisTemplate.opsForValue().set(registerImgRo.getPhone() +
                    Constant.REGISTER_PHONE,newCode,5, TimeUnit.MINUTES);
            System.out.println(newCode);//模拟发送短信
        }else {
            //如果在1分钟之内  提示 你太快了
            Long expire =
                    redisTemplate.getExpire(registerImgRo.getPhone() + Constant.REGISTER_PHONE);//返回当前key的剩余过期时间
            if(expire > 240){
                throw new BusinessException("手速太快了");
            }
            System.out.println(oldCode.toString());//模拟发送短信
            redisTemplate.opsForValue().set(registerImgRo.getPhone() +
                    Constant.REGISTER_PHONE,oldCode.toString(),5, TimeUnit.MINUTES);
        }
        //  验证码
        //  发送验证码
        return AjaxResult.me();
    }

    @Override
    public AjaxResult userPhone(RegisterUserPhoneRo userPhoneRo) {
        // 校验  JSR303
        //分析
        if(!userPhoneRo.getPassword().equals(userPhoneRo.getPasswordRepeat())){
            throw new BusinessException("两次密码不一致");
        }
        //判断手机验证码对不对
        Object oldCode = redisTemplate.opsForValue().get(userPhoneRo.getPhone() +
                Constant.REGISTER_PHONE);
        if(oldCode == null){
            throw new BusinessException("手机验证码已过期");
        }
        if(!userPhoneRo.getPhoneCode().equals(oldCode.toString())){
            throw new BusinessException("手机验证码输入错误");
        }
        //验证手机号是否已经注册
        User user = userMapper.findUserByPhone(userPhoneRo.getPhone());
        if(user != null){
            throw new BusinessException("该手机号已经被注册");
        }
        // 注册 有两张表要保存
        String salt = RandomUtil.randomString(32);
        String newPassword = SecureUtil.md5(salt + userPhoneRo.getPassword());

        Logininfo logininfo = buildLogininfo(userPhoneRo, salt, newPassword);

        userMapper.save(buildUser(userPhoneRo,salt, newPassword,logininfo.getId()));

        return AjaxResult.me();
    }

    private Logininfo buildLogininfo(RegisterUserPhoneRo userPhoneRo, String salt, String newPassword) {
        Logininfo logininfo = new Logininfo();
        logininfo.setType(1);
        logininfo.setDisable(true);
        logininfo.setPhone(userPhoneRo.getPhone());
        logininfo.setUsername(userPhoneRo.getPhone());
        logininfo.setSalt(salt);
        logininfo.setPassword(newPassword);
        logininfoMapper.save(logininfo);
        return logininfo;
    }

    private User buildUser(RegisterUserPhoneRo userPhoneRo,String salt, String newPassword,Long logininfoId){
        User user = new User();
        user.setUsername(userPhoneRo.getPhone());//没有用户名 就用手机号代替
        user.setPhone(userPhoneRo.getPhone());//没有用户名 就用手机号代替
        user.setCreatetime(new Date());
        user.setLogininfoId(logininfoId);
        user.setSalt(salt);
        user.setPassword(newPassword);
        user.setState(1);
        return user;
    }
}
